﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Jemgine.Engine.Particles
{
	public class ParticleModule : Module
	{
        Jemgine.Particles.ParticleRenderer Renderer;
        Dictionary<String, Jemgine.Particles.ParticleEffect> Effects = new Dictionary<string,Jemgine.Particles.ParticleEffect>();
        ContentManager episodeContent;
        GraphicsDevice graphicsDevice;

        public void FireEffect(ParticleEmitter Emitter)
        {
            if (Emitter == null || String.IsNullOrEmpty(Emitter.Effect)) return;
            var Position = Emitter.GetAnimatedWorldPosition();
            var Angle = Emitter.GetAnimatedAngle(Emitter.EmissionAngle);
            FireEffect(Position, Angle, Emitter.Effect);
        }

        public void FireEffect(Vector2 Position, float Angle, String EffectName)
        {
            if (Effects.ContainsKey(EffectName))
            {
                var Effect = Effects[EffectName];
                if (Effect != null) Effect.Emit(Position, Angle);
            }
            else
            {
                try
                {
                    var Effect = episodeContent.Load<Jemgine.Particles.ParticleEffect>(EffectName);
                    Effect.Initialize(graphicsDevice, episodeContent);
                    Effects.Add(EffectName, Effect);
                    Effect.Emit(Position, Angle);
                }
                catch (ContentLoadException)
                {
                    Effects.Add(EffectName, null);
                }
            }
        }

		public ParticleModule(Settings settings, GraphicsDevice device, ContentManager EffectContent,
            ContentManager EpisodeContent)
		{
            Renderer = new Jemgine.Particles.ParticleRenderer();
            Renderer.Initialize(device, EffectContent);

            graphicsDevice = device;
            episodeContent = EpisodeContent;
		}

        public override void  EndSimulation()
        {
 	        foreach (var Effect in Effects) 
                Effect.Value.ReleaseBuffers();
            Effects.Clear();
        }

        public override void BeginSimulation()
		{
		}
        
        public override void Update(float ElapsedSeconds)
        {
            if (Sim.SupressPhysics) return;

            foreach (var Effect in Effects)
                if (Effect.Value != null) Effect.Value.Update(ElapsedSeconds);
        }

        public override void Draw(Renderer.RenderEffect Effect, Renderer.VertexPusher Pusher)
        {
            Render(Sim.CameraModule.Camera);
        }

        public void Render(Renderer.Camera Camera)
        {
            Renderer.View = Camera.View;
            Renderer.World = Camera.World;
            Renderer.Projection = Camera.Projection;

            foreach (var Effect in Effects)
                Renderer.Draw(Effect.Value);
        }
	}
}
